package com.cea.papyrus.core.ui.dialogs;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Stereotype;

import com.cea.papyrus.profile.ui.dialogs.AlphabeticalViewerSorter;
import com.cea.papyrus.profile.ui.dialogs.StereotypeLabelProvider;
import com.cea.papyrus.profile.ui.dialogs.StereotypeQualifiedLabelProvider;

/**
 * Selection Dialog for  a set of elements, with a returned list of stereotypes to apply 
 */
public class ApplyStereotypeSelectionDialog extends com.cea.papyrus.profile.ui.dialogs.ChooseSetAssistedDialog {

	/** LabelProvider for stereotype completion proposal provider with qualified names */
	final private StereotypeQualifiedLabelProvider qualifiedLabelProvider = new StereotypeQualifiedLabelProvider();
	
	public ApplyStereotypeSelectionDialog(Shell parentShell, Element element) {
		super(parentShell, "Applicable Stereotypes: ", "Stereotypes to apply: ");
		labelProvider = new StereotypeLabelProvider();
		decoratedContentProposalProvider = new StereotypeContentProposalProvider();
		
		// fill the list of applicable stereotypes
		Iterator stereotypes = element.getApplicableStereotypes().iterator();
		while (stereotypes.hasNext()){
			possibleElementList.addElement((Stereotype)stereotypes.next());
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText("Choose stereotypes to apply");
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.ui.dialogs.ChooseSetAssistedDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Control composite = super.createDialogArea(parent);
		
		// Add 2 columns to the table area
		// possibleElementsTable.setLinesVisible(true);
		possibleElementsTable.setHeaderVisible(true);

		// 1st column with image/checkboxes - NOTE: The SWT.CENTER has no effect!!
		TableColumn column = new TableColumn(possibleElementsTable, SWT.CENTER, 0);		
		column.setText("Stereotype");
		column.setWidth(150);
		column.addSelectionListener(new SelectionAdapter() {
	       	
			@Override
			public void widgetSelected(SelectionEvent e) {
				possibleElementsTableViewer.setSorter(new AlphabeticalViewerSorter(0));
			}
		});
		
		// 2nd column with task Description
		column = new TableColumn(possibleElementsTable, SWT.LEFT, 1);
		column.setText("Information");
		column.setWidth(165);
		// Add listener to column so tasks are sorted by description when clicked 
		column.addSelectionListener(new SelectionAdapter() {
       	
			@Override
			public void widgetSelected(SelectionEvent e) {
				possibleElementsTableViewer.setSorter(new AlphabeticalViewerSorter(1));
			}
		});

		// set sorter to the possible element table viewer 
		possibleElementsTableViewer.setSorter(new AlphabeticalViewerSorter(0));
		
		return composite;
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.ui.dialogs.ChooseSetAssistedDialog#runAddElement(java.lang.String)
	 */
	@Override
	protected void runAddElement(String name) {
		// find the stereotype in the list
		Stereotype stereotype =null;
		Iterator<Stereotype> it = possibleElementList.getElements().iterator();
		while (it.hasNext()) {
			Stereotype element = (Stereotype) it.next();
			if( name.equalsIgnoreCase(element.getName()) || name.equalsIgnoreCase(element.getQualifiedName())) {
				stereotype = element;
			}
		}
		if(stereotype != null) {
			runActionAdd(stereotype);
		}
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.core.ui.dialogs.ChooseSetAssistedDialog#isSelectableElement(java.lang.String)
	 */
	@Override
	protected boolean isSelectableElement(String text) {
		// iterate through all possibilities and return true if text corresponds
		Iterator<Stereotype> it = possibleElementList.getElements().iterator();
		while (it.hasNext()) {
			Stereotype element = (Stereotype) it.next();
			if( text.equalsIgnoreCase(element.getName()) || text.equalsIgnoreCase(element.getQualifiedName())) {
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * Content Proposal provider for stereotypes dialog. Propose the simple
	 * name of the stereotype and its qualified name.
	 */
	public class StereotypeContentProposalProvider extends DecoratedContentProposalProvider {

		/* (non-Javadoc)
		 * @see com.cea.papyrus.core.ui.dialogs.ChooseSetAssistedDialog.DecoratedContentProposalProvider#getProposals(java.lang.String, int)
		 */
		@Override
		public DecoratedContentProposal[] getProposals(String contents, int position) {
			ArrayList<DecoratedContentProposal> proposals = new ArrayList<DecoratedContentProposal>();

			if(possibleElementList != null) {
				Iterator it = possibleElementList.getElements().iterator();
				while(it.hasNext()) {
					final Stereotype stereotype = (Stereotype)it.next();
					final String simpleName = stereotype.getName();
					final String qualifiedName = stereotype.getQualifiedName();

					if( position < simpleName.length() && contents.substring(0, position).equalsIgnoreCase(simpleName.substring(0, position))) {
						proposals.add(new DecoratedContentProposal(stereotype, labelProvider));
					}

					if( position < qualifiedName.length() && contents.substring(0, position).equalsIgnoreCase(qualifiedName.substring(0, position))) {
						proposals.add(new DecoratedContentProposal(stereotype, qualifiedLabelProvider));
					}
				}
			}
			
			Collections.sort(proposals);
			return proposals.toArray(new DecoratedContentProposal[proposals.size()]);
		}
	}
}
